import 'package:flutter/material.dart';

import '../../api/models/todos_model.dart';
import '../../http/rest_api_base_model.dart';

class TodoViewModel extends ChangeNotifier {
  TodoQueryRequest _query = TodoQueryRequest();
  List<TodoItemModel> _todos = [];
  bool _isLoading = false;
  bool _hasMore = true;

  List<TodoItemModel> get todos => _todos;

  bool get isLoading => _isLoading;

  bool get hasMore => _hasMore;

  TodoQueryRequest get query => _query;

  TodoFilterModel _filter = TodoFilterModel();

  TodoFilterModel get filter => _filter;

  void updateFilter(TodoFilterModel newFilter) {
    _filter = newFilter;
    // 将过滤条件合并到查询条件
    _query = _query.copyWith(filter: newFilter);
    fetchTodos();
  }

  /// 更新查询条件并刷新
  void updateQuery(TodoQueryRequest newQuery) {
    _query = newQuery.copyWith(page: 1);
    _todos.clear();
    _hasMore = true;
    fetchTodos();
  }

  /// 加载更多
  Future<void> loadMore() async {
    if (_isLoading || !_hasMore) return;
    _query = _query.copyWith(page: _query.page + 1);
    await fetchTodos(append: true);
  }

  /// 核心查询方法
  Future<void> fetchTodos({bool append = false}) async {
    _isLoading = true;
    notifyListeners();

    try {
      var queryBody = {
        "searchInput": "",
        "startTime": _query.filter?.startDate?.toIso8601String() ?? "",
        "endTime": _query.filter?.endDate?.toIso8601String() ?? "",
        "pageNum": _query.page,
        "pageSize": _query.pageSize,
        "orderByColumn": _query.sortField.label,
        "isAsc": _query.sortOrder.name,
      };

      PageableResponse<TodoItemModel> pResp = PageableResponse(
          pagination: Pagination(
              total: 0,
              pageNum: 0,
              pageSize: 0,
              totalPages: 0,
              hasNext: false,
              hasPrev: false,
              first: 0,
              last: 0),
          data: []);

      if (append) {
        _todos.addAll(pResp.data);
      } else {
        _todos = pResp.data;
      }
      _hasMore = pResp.pagination.hasNext;
    } catch (e) {
      // TODO: 错误处理
    } finally {
      _isLoading = false;
      notifyListeners();
    }
  }
}

enum CategoryOption {
  all(label: ''),
  cx1104(label: 'cx1104'),
  cx1108(label: 'cx1108');

  final String label;

  const CategoryOption({required this.label});

  get catId => label;
}

enum TodoSortField {
  createTime(field: 'todo_time'),
  handleTime(field: 'handle_time');

  final String field;

  const TodoSortField({required this.field});

  get label => field;
}

enum TodoSortOrder { asc, desc }

enum TodoFilterStatus { all, pending, completed }

class TodoQueryRequest {
  final String? categoryId;
  final TodoSortField sortField;
  final TodoSortOrder sortOrder;
  final TodoFilterModel? filter = TodoFilterModel();
  final int page;
  final int pageSize;

  TodoQueryRequest({
    this.categoryId,
    this.sortField = TodoSortField.createTime,
    this.sortOrder = TodoSortOrder.desc,
    this.page = 1,
    this.pageSize = 20,
  });

  TodoQueryRequest copyWith({
    String? categoryId,
    TodoSortField? sortField,
    TodoSortOrder? sortOrder,
    TodoFilterModel? filter,
    int? page,
    int? pageSize,
  }) {
    return TodoQueryRequest(
      categoryId: categoryId ?? this.categoryId,
      sortField: sortField ?? this.sortField,
      sortOrder: sortOrder ?? this.sortOrder,
      page: page ?? this.page,
      pageSize: pageSize ?? this.pageSize,
    );
  }
}

class TodoFilterModel {
  final TodoFilterStatus status;
  final DateTime? startDate;
  final DateTime? endDate;

  TodoFilterModel({
    this.status = TodoFilterStatus.all,
    this.startDate,
    this.endDate,
  });

  TodoFilterModel copyWith({
    TodoFilterStatus? status,
    DateTime? startDate,
    DateTime? endDate,
  }) {
    return TodoFilterModel(
      status: status ?? this.status,
      startDate: startDate ?? this.startDate,
      endDate: endDate ?? this.endDate,
    );
  }
}
